import { lazy, Suspense } from 'react'
import { createBrowserRouter, Navigate, redirect, RouteObject, useRouteError } from 'react-router-dom'
import {
  getItem,
  TOKEN,
  hsHandleLoginCode,
  PERMISSIONROUTERLIST,
  __DEV__,
  getUrlSearchParams,
  setItem,
  hsHandleUserAuth,
  generateEnableRouter,
  DEMO_TOKEN_PROD,
  DEMO_TOKEN_SIT
} from '@hs-admin/utils'
import { originMenuOptions } from '@/utils/menu'
import { Flex, Skeleton } from 'antd'
import { codeGetToken, getUserInfo, refreshToken } from '@/api/login'
import { commonRouteLoader } from '@hs-admin/node'

const Layout = lazy(() => import('@/views/Layout'))
const Login = lazy(() => import('@/views/Login'))
const Demo = lazy(() => import('@/views/Demo'))
const Overview = lazy(() => import('@/views/Overview'))
const MarketBasicData = lazy(() => import('@/views/MarketBasicData'))
const MarketBasicThemeDetail = lazy(() => import('@/views/MarketBasicData/themeDetail'))
const MarketBasicThemeDataItemDetail = lazy(() => import('@/views/MarketBasicData/DataItemDetail'))
const MarketIndustryData = lazy(() => import('@/views/MarketIndustryData'))
const MarketIndustryThemeDetail = lazy(() => import('@/views/MarketIndustryData/themeDetail'))
const MarketIndustryThemeDataItemDetail = lazy(() => import('@/views/MarketIndustryData/DataItemDetail'))
const MarketProductItemSet = lazy(() => import('@/views/MarketDataProduct/ItemSet'))
const MarketProductWebsite = lazy(() => import('@/views/MarketDataProduct/Website'))
const OperationBasic = lazy(() => import('@/views/OperationBasic'))
const OperationBasicTheme = lazy(() => import('@/views/OperationBasic/DataTheme'))
const OperationBasicItem = lazy(() => import('@/views/OperationBasic/DataItem'))
const OperationBasicItemDetail = lazy(() => import('@/views/OperationBasic/DataItem/ItemDetail'))
const OperationIndustry = lazy(() => import('@/views/OperationIndustry'))
const OperationIndustryDomain = lazy(() => import('@/views/OperationIndustry/Domain'))
const OperationIndustryAtlas = lazy(() => import('@/views/OperationIndustry/Atlas'))
const OperationIndustryAtlasDetail = lazy(() => import('@/views/OperationIndustry/Atlas/Detail'))
const DataService = lazy(() => import('@/views/DataService'))
const MyDataService = lazy(() => import('@/views/DataService/my'))
const ShoppingCart = lazy(() => import('@/views/ShoppingCart/ShoppingCart.tsx'))
const ShoppingOrderList = lazy(() => import('@/views/ShoppingCart/OrderList.tsx'))
const ShoppingOrderDetail = lazy(() => import('@/views/ShoppingCart/OrderDetail.tsx'))
const SubmitShoppingOrder = lazy(() => import('@/views/ShoppingCart/SubmitShoppingOrder.tsx'))
const DocMaintain = lazy(() => import('@/views/operationCenter/DocMaintain'))
const DocMaintainView = lazy(() => import('@/views/operationCenter/DocMaintainView'))
const ProjectView = lazy(() => import('@/views/DeveloperCenter/Project'))
const TagsView = lazy(() => import('@/views/Tags'))
const ItemSetNav = lazy(() => import('@/views/OperationDataProduct/ItemSetNav'))
const ItemSetCategory = lazy(() => import('@/views/OperationDataProduct/ItemSet/Category'))
const ItemSetChild = lazy(() => import('@/views/OperationDataProduct/ItemSet/Child'))
const WebsiteNav = lazy(() => import('@/views/OperationDataProduct/WebsiteNav'))
const WebsiteCategory = lazy(() => import('@/views/OperationDataProduct/Website/Category'))
const WebsiteChild = lazy(() => import('@/views/OperationDataProduct/Website/Child'))

function withLoading(compnent: JSX.Element) {
  return <Suspense fallback={<Skeleton active />}>{compnent}</Suspense>
}

const routeChildren: Array<{
  name?: string
  path: string
  element: JSX.Element
  children?: any[]
  loader?: (params?: any, prefix?: string) => null
}> = [
  {
    path: '*',
    element: withLoading(<Navigate to="/overview" replace />)
  },
  {
    path: '',
    element: withLoading(<Navigate to="/overview" replace />)
  },
  {
    path: 'overview',
    element: withLoading(<Overview />)
  },
  {
    path: 'marketBasicData',
    element: withLoading(<MarketBasicData />)
  },
  {
    path: 'marketBasicData/themeDetail',
    element: withLoading(<MarketBasicThemeDetail />)
  },
  {
    path: 'dataItemDetail',
    element: withLoading(<MarketBasicThemeDataItemDetail />)
  },
  {
    path: 'marketIndustryData',
    element: withLoading(<MarketIndustryData />)
  },
  {
    path: 'marketIndustryData/themeDetail',
    element: withLoading(<MarketIndustryThemeDetail />)
  },
  {
    path: 'marketIndustryData/themeDetail/dataItemDetail',
    element: withLoading(<MarketIndustryThemeDataItemDetail />)
  },
  {
    path: 'marketItemSet',
    element: withLoading(<MarketProductItemSet />)
  },
  {
    path: 'marketWebsite',
    element: withLoading(<MarketProductWebsite />)
  },
  {
    path: 'tags',
    element: withLoading(<TagsView />)
  },
  {
    path: 'DocMaintain',
    element: withLoading(<DocMaintain />)
  },
  {
    path: 'DocMaintainView',
    element: withLoading(<DocMaintainView />)
  },
  {
    path: 'operationBasic',
    element: withLoading(<OperationBasic />),
    children: [
      {
        path: 'theme',
        element: withLoading(<OperationBasicTheme />)
      },
      {
        path: 'item',
        element: withLoading(<OperationBasicItem />)
      },
      {
        path: 'itemDetail',
        element: withLoading(<OperationBasicItemDetail />)
      }
    ]
  },
  {
    path: 'operationIndustry',
    element: withLoading(<OperationIndustry />),
    children: [
      {
        path: 'domain',
        element: withLoading(<OperationIndustryDomain />)
      },
      {
        path: 'atlas',
        element: withLoading(<OperationIndustryAtlas />)
      },
      {
        path: 'atlasDetail',
        element: withLoading(<OperationIndustryAtlasDetail />)
      }
    ]
  },
  {
    path: 'itemSet',
    element: withLoading(<ItemSetNav />),
    children: [
      {
        path: 'category',
        element: withLoading(<ItemSetCategory />)
      },
      {
        path: 'list',
        element: withLoading(<ItemSetChild />)
      }
    ]
  },
  {
    path: 'website',
    element: withLoading(<WebsiteNav />),
    children: [
      {
        path: 'category',
        element: withLoading(<WebsiteCategory />)
      },
      {
        path: 'list',
        element: withLoading(<WebsiteChild />)
      }
    ]
  },
  {
    path: 'dataService',
    element: withLoading(<DataService />)
  },
  {
    path: 'myDataService',
    element: withLoading(<MyDataService />)
  },
  {
    path: 'submitShoppingOrder',
    element: withLoading(<SubmitShoppingOrder />)
  },
  {
    path: 'shoppingOrderList',
    element: withLoading(<ShoppingOrderList />)
  },
  {
    path: 'shoppingOrderDetail',
    element: withLoading(<ShoppingOrderDetail />)
  },
  {
    path: 'myShoppingOrderList',
    element: withLoading(<ShoppingOrderList />)
  },
  {
    path: 'shoppingCart',
    element: withLoading(<ShoppingCart />)
  },
  {
    path: 'project',
    element: withLoading(<ProjectView />)
  }
]
if (__DEV__) {
  routeChildren.push({
    path: 'demo',
    element: withLoading(<Demo />)
  })
}
routeChildren.forEach((first) => {
  first.loader ??= commonRouteLoader
  first.children?.forEach((second) => {
    second.loader ??= commonRouteLoader
  })
})

function ErrorBoundary() {
  const error = useRouteError() as {
    message?: string
    status?: number
  }
  let text = ''
  if (error.message?.includes('Failed to fetch dynamically imported module')) {
    text = '页面已发新版，请强刷页面或清空缓存'
    window.location.reload()
  } else if (error.message?.length) {
    text = error.message
  } else if (error.status === 404) {
    text = '页面不存在'
  } else if (error.status === 403) {
    text = '您没有该页面权限'
  } else {
    text = '未知错误'
    console.error(error)
  }
  return (
    <Flex align="center" justify="center" style={{ height: '100%' }}>
      <h1>{text}</h1>
    </Flex>
  )
}

const routeConfig: RouteObject[] = [
  {
    path: '/',
    element: withLoading(<Layout />),
    children: routeChildren,
    loader: async ({ request }) => {
      // demo演示
      if (getUrlSearchParams('from') === 'demo') {
        let demoToken = DEMO_TOKEN_PROD
        if (import.meta.env.VITE_ENV === 'sit') {
          demoToken = DEMO_TOKEN_SIT
        }
        setItem(TOKEN, demoToken)
        if (getUrlSearchParams('small')) {
          setItem('smallScreen', 1)
        }
        return refreshToken({}).then((res) => {
          setItem(TOKEN, res.access_token)
          return getUserInfo()
            .then((res) => {
              hsHandleUserAuth(res)
              generateEnableRouter(originMenuOptions)
              return null
            })
            .catch((error) => {
              return Promise.reject(error)
            })
        })
      }
      // 门户页跳转过来
      if (getUrlSearchParams(TOKEN)) {
        setItem(TOKEN, getUrlSearchParams(TOKEN) || '')
        return getUserInfo()
          .then((res) => {
            hsHandleUserAuth(res)
            generateEnableRouter(originMenuOptions)
            location.search = ''
            return redirect('/')
          })
          .catch((error) => {
            return Promise.reject(error)
          })
      }
      const token = getItem(TOKEN)
      if (!token) {
        return redirect('/login')
      }
      return null
      // 校验跳转路由是否有权限
      const configMenuList = getItem(PERMISSIONROUTERLIST) || []
      const _isPass = configMenuList.some((item: string) => request.url.includes(item))
      if (_isPass) {
        return null
      } else {
        if (configMenuList[0]) return redirect(configMenuList[0])
        else
          throw {
            message: __DEV__ ? '开发者提示：localstorage数据有误，请重新登录' : '无页面权限'
          }
      }
    },
    errorElement: <ErrorBoundary />
  },
  {
    path: '/login',
    element: withLoading(<Login />),
    loader: async ({ request }) => {
      return hsHandleLoginCode(request.url, originMenuOptions, codeGetToken, getUserInfo)
    },
    errorElement: <ErrorBoundary />
  }
]

const router = createBrowserRouter(routeConfig)

// Clean up on module reload (HMR)
// https://vitejs.dev/guide/api-hmr
if (import.meta.hot) {
  import.meta.hot.dispose(() => router.dispose())
}

export default router
